const crypto = require('crypto');
const axios = require('axios');
const apiUrl = {
    // 即时查询
    query: 'http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx',
}

class Api {

    constructor(config) {
        config = {
            ...config
        }

        this.config = config;
        this.axios = this.createAxios();
    }

    createAxios() {

        const instance = axios.create({});

        instance.interceptors.request.use(
            config => {

                config = {
                    ...config,
                }

                if (config.headers['Content-Type'] == undefined) {
                    config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
                    config.transformRequest = [function(data) {
                        let ret = ''
                        for (let key in data) {
                            let item = data[key];
                            //过滤null以及undefined by yc
                            if (item == null || item == undefined) {
                                item = ""
                            }
                            ret += encodeURIComponent(key) + '=' + encodeURIComponent(item) + '&'
                        }
                        return ret
                    }]
                }

                config.onSuccess = Promise.resolve;
                config.onFail = (error, res) => Promise.reject([error, res]);

                if (config.debug) console.log(config);

                return config;
            },
            error => {
                return Promise.reject([error])
            }
        )

        instance.interceptors.response.use(
            async response => {
                    const { config, status } = response;

                    if (status == 200) {
                        const data = response.data;

                        if (data.Success) {
                            return data;
                        } else {
                            return config.onFail(data.Reason, data);
                        }
                    } else {
                        throw '微信服务器异常'
                    }
                },
                error => {
                    const { config, response } = error;

                    if (response) {
                        return config.onFail('服务器异常', response.data);
                    } else {

                        if (config) {
                            return config.onFail(error.message, error);
                        } else {
                            return Promise.reject([error])
                        }
                    }
                }
        )

        return instance;
    }

    /**
     * 即时查询API
     * http://www.kdniao.com/v2/API/Track.aspx
     * @param companyCode 快递公司编码
     * @param expCode 快递单号
     * @return 标准Promise
     */
    async query(options) {

        options = {
            eBusinessID: this.config.eBusinessID,
            appKey: this.config.appKey,
            ...options,
        }

        const { companyCode, expressNo, eBusinessID, appKey } = options;

        const requestData = {
            OrderCode: '',
            ShipperCode: companyCode,
            LogisticCode: expressNo
        }

        const data = {
            RequestData: encodeURI(JSON.stringify(requestData)),
            EBusinessID: eBusinessID,
            RequestType: '1002',
            DataType: '2',
        }

        data.DataSign = encrypt(requestData, appKey);

        return this.axios({
            method: 'POST',
            url: apiUrl.query,
            data,
        })
    }
}

/**
 * 签名生成
 */
function encrypt(requestData, appKey, charset = 'utf8') {
    const content = JSON.stringify(requestData)

    return encodeURI(base64(MD5(content + appKey, charset), charset))
}

/**
 * MD5加密
 */
function MD5(content, charset) {
    return crypto.createHash('md5').update(content, charset).digest('hex');
}

/**
 * base64编码
 */
function base64(content) {
    var b = new Buffer.from(content);

    return b.toString("base64")
}

module.exports = Api;